﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Model;
using Interfaces;
using System.Data;
using System.Collections;

namespace Controller
{
    public class EmmaSystem
    {
        // Attributter 
        private PosteringsColl posteringsColl; // Aggregering af en collection-klasse
        private ÅrsregnskabsColl årsregnskabsColl;
        private DBFacaden dbFacade;     // aggregering af database-facaden
        private MailAccount mailAccount;    // aggregering af mailAccount-klassen
        private MedarbejderColl medarbejderColl;
        private KundeColl kundeColl;
        private ProjektColl projektColl;
        private FakturaColl fakturaColl;

        private List<int> tidsListe;    // liste til metoden IndlæsTidArbejdslog

        #region Attributter til rapportgenerering

        private IÅrsregnskabsdata iÅrsregnskab;
        private List<IFakturadata> iFaktura;
        private List<IVaredata> iVarer;
        private double nettoOmsætning;
        private double produktionsomkostning;
        private double bruttoresultat;
        private double distributionsomkostning;
        private double administrationsomkostning;
        private double resultatPrimærDrift;
        private double finansielOmkostningNetto;
        private double åretsResultat;
        private double anlægsaktiver;
        private double omsætningsaktiver;
        private double aktiverIAlt;
        private double egenkapital;
        private double gældsforpligtelser;
        private double passiverIAlt;
        private double afkastningsgrad;
        private double overskudsgrad;
        private double aktivernesOmsætningshastighed;
        private double egenkapitalensForretning;
        private double fremmedkapitalensForretning;
        private double dækningsgrad;
        private double nulpunktsomsætning;
        private double sikkerhedsMargin;
        private double kapacitetsgrad;
        private double anlægsaktivernesOmsætningshastighed;
        private double materielleOmsætningshastighed;
        private double varelagrenesOmsætningshastighed;
        private double lagerdage;
        private double varedebitorernesOmsætningshastighed;
        private double kreditdage;
        private double soliditetsgrad;
        private double likviditetsgrad1;
        private double likviditetsgrad2;

        #endregion

        // Konstruktør
        public EmmaSystem()
        {
            posteringsColl = new PosteringsColl();
            årsregnskabsColl = new ÅrsregnskabsColl();
            dbFacade = new DBFacaden(this);
            mailAccount = new MailAccount();
            medarbejderColl = new MedarbejderColl();
            kundeColl = new KundeColl();
            projektColl = new ProjektColl();
            fakturaColl = new FakturaColl();

            dbFacade.IndlæsFraDatabase();    // Indlæs fra database til model under opstart
            tidsListe = new List<int>();
            
            iVarer = new List<IVaredata>();     // liste til rapportgenerering
            iFaktura = new List<IFakturadata>();    // liste til rapportgenerering
        }

        #region Operationer på posteringsobjekter

        // Metode til at associere et årsregnskabs-objekt til et posterings-objekt og omvendt
        public void AssocierÅrsregnskabOgPostering(int årstal, long bilagsNr)
        {
            Postering postering = posteringsColl.FindPostering(bilagsNr);
            Årsregnskab årsregnskab = årsregnskabsColl.FindÅrsregnskab(årstal);

            årsregnskabsColl.TilknytPostering(årsregnskab.Årstal, postering);
            posteringsColl.TilknytÅrsregnskab(bilagsNr, årsregnskab);
        }

        // Metode til at fjerne associeringen mellem et årsregnskabs-objekt og et posterings-objekt
        public void FjernAssocieringMellemÅrsregnskabOgPostering(long bilagsNr)
        {
            Postering postering = posteringsColl.FindPostering(bilagsNr);
            Årsregnskab årsregnskab = posteringsColl.GetÅrsregnskab(bilagsNr);

            årsregnskabsColl.FjernPosteringsTilknytning(årsregnskab.Årstal, postering);
            posteringsColl.FjernÅrsregnskabsTilknytning(bilagsNr);
        }

        // Metode til at indlæse posterings-objekter i systemet
        public void IndlæsPosteringer(long bilagsNr, string posteringsType, string beskrivelse, double beløb, DateTime dato, bool aktiv, int årstal)
        {
            posteringsColl.OpretPostering(bilagsNr, posteringsType, beskrivelse, beløb, dato, aktiv);
            AssocierÅrsregnskabOgPostering(årstal, bilagsNr);
        }

        // Metode til at oprette en posterings-objekt i systemet og databasen
        public bool OpretPostering(long bilagsNr, string posteringsType, string beskrivelse, double beløb, DateTime dato, bool aktiv)
        {
            int årstal = Convert.ToInt32(dato.Year);

            Årsregnskab årsregnskab = årsregnskabsColl.FindÅrsregnskab(årstal);
            if (årsregnskab != null)
            {
                if (dbFacade.OpretPostering(bilagsNr, posteringsType, beskrivelse, beløb, dato, aktiv, årstal))
                {
                    posteringsColl.OpretPostering(bilagsNr, posteringsType, beskrivelse, beløb, dato, aktiv);
                    AssocierÅrsregnskabOgPostering(årstal, bilagsNr);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                if (dbFacade.OpretÅrsregnskab(årstal))
                {
                    årsregnskabsColl.OpretÅrsregnskab(årstal);

                    if (dbFacade.OpretPostering(bilagsNr, posteringsType, beskrivelse, beløb, dato, aktiv, årstal))
                    {
                        posteringsColl.OpretPostering(bilagsNr, posteringsType, beskrivelse, beløb, dato, aktiv);
                        AssocierÅrsregnskabOgPostering(årstal, bilagsNr);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
        }

        // Metode til at annullere et posterings-objekt i systemet og databasen
        public bool AnnullerPostering(long bilagsNr, bool aktiv)
        {
            if (dbFacade.AnnullerPostering(bilagsNr, aktiv))
            {
                FjernAssocieringMellemÅrsregnskabOgPostering(bilagsNr);
                posteringsColl.AnnullerPostering(bilagsNr, aktiv);
                return true;
            }
            else
            {
                return false;
            }
        }

        // Kald af metode til at hente en iterator, der gennemløber posterings-objekterne
        public IEnumerator GetPosteringer()
        {
            return posteringsColl.GetPosteringer();
        }

        // Metode til at hente en liste med posterings-objekterne (metoden er tilføjet af hensyn til rapportgenereringen)
        public List<IPosteringsdata> GetPosteringsliste()
        {
            // byg liste af IPosteringsdata
            List<IPosteringsdata> posteringsliste = new List<IPosteringsdata>();
            IEnumerator postIterator = GetPosteringer();
            postIterator.Reset();
            while (postIterator.MoveNext())
            {
                posteringsliste.Add((Postering)postIterator.Current);
            }

            return posteringsliste;
        }

        #endregion

        #region Operationer på årsregnskabs-objekter

        #region Metoder til at oprette, redigere, finde og returnere iterator

        // Metode til at indlæse et årsregnskabs-objekt i systemet
        public void IndlæsÅrsregnskaber(int årstal, double immaterielle, double materielle, double finansielle, double varebeholdninger,
            double tilgodehavender, double værdipapirer, double likvideBeholdninger, double aktiekapital, double overførteOverskud,
            double forslagTilUdbytte, double hensatteForpligtelser, double langfristetGæld, double kortfristetGæld)
        {
            årsregnskabsColl.OpretÅrsregnskab(årstal);
            årsregnskabsColl.RedigerÅrsregnskab(årstal, immaterielle, materielle, finansielle, varebeholdninger, tilgodehavender,
                værdipapirer, likvideBeholdninger, aktiekapital, overførteOverskud, forslagTilUdbytte, hensatteForpligtelser,
                langfristetGæld, kortfristetGæld);
        }

        // Metode til at redigere et årsregnskab i systemet og i databasen
        public bool OpstilÅrsregnskab(int årstal, double immaterielle, double materielle, double finansielle, double varebeholdninger,
            double tilgodehavender, double værdipapirer, double likvideBeholdninger, double aktiekapital, double overførteOverskud,
            double forslagTilUdbytte, double hensatteForpligtelser, double langfristetGæld, double kortfristetGæld)
        {
            if (dbFacade.RedigerÅrsregnskab(årstal, immaterielle, materielle, finansielle, varebeholdninger, tilgodehavender,
                værdipapirer, likvideBeholdninger, aktiekapital, overførteOverskud, forslagTilUdbytte, hensatteForpligtelser,
                langfristetGæld, kortfristetGæld))
            {
                årsregnskabsColl.RedigerÅrsregnskab(årstal, immaterielle, materielle, finansielle, varebeholdninger, tilgodehavender,
                værdipapirer, likvideBeholdninger, aktiekapital, overførteOverskud, forslagTilUdbytte, hensatteForpligtelser,
                langfristetGæld, kortfristetGæld);
                return true;
            }
            else
            {
                return false;
            }
        }

        // kald af metode til at returnere iterator, der gennemløber årsregnskaberne
        public IEnumerator GetÅrsregnskaber()
        {
            return årsregnskabsColl.GetÅrsregnskaber();
        }

        // metode til at give objektet/attributt iÅrsregnskab sit indhold
        public void UdfyldIÅrsregnskab(int årstal)
        {
            IÅrsregnskabsdata iÅr;
            IEnumerator iÅrIterator = GetÅrsregnskaber();
            iÅrIterator.Reset();

            while (iÅrIterator.MoveNext())
            {
                iÅr = (IÅrsregnskabsdata)iÅrIterator.Current;

                if (iÅr.Årstal == årstal)
                {
                    iÅrsregnskab = iÅr;
                }
            }
        }

        #endregion

        #region Metoder til at sammenligne nøgletal

        // kald af metode til at sætte sætte et år som indekstal
        public int SætÅrSomIndeks()
        {
            return årsregnskabsColl.SætÅrSomIndeks();
        }

        // kald af metode til at udregne indekstal på omsætning
        public double GetIndekstalOmsætning(int årstal, int årstalBasisår)
        {
            return årsregnskabsColl.GetIndekstalOmsætning(årstal, årstalBasisår);
        }

        // kald af metode til at udregne indekstal på produktionsomkostninger
        public double GetIndekstalProduktionsomkostninger(int årstal, int årstalBasisår)
        {
            return årsregnskabsColl.GetIndekstalProduktionsomkostninger(årstal, årstalBasisår);
        }

        // kald af metode til at udregne indekstal på distributionsomkostninger
        public double GetIndekstalDistributionsomkostninger(int årstal, int årstalBasisår)
        {
            return årsregnskabsColl.GetIndekstalDistributionsomkostninger(årstal, årstalBasisår);
        }

        // kald af metode til at udregne indekstal på administrationsomkostninger
        public double GetIndekstalAdministrationsomkostninger(int årstal, int årstalBasisår)
        {
            return årsregnskabsColl.GetIndekstalAdministrationsomkostninger(årstal, årstalBasisår);
        }

        #endregion

        #region Metoder til at udregne de forskellige værdier i resultatopgørelsen og balance

        // metode til at udregne de forskellige værdier i resultatopgørelsen
        public void UdregnResultatopgørelse(int årstal)
        {
            nettoOmsætning = årsregnskabsColl.GetNettoomsætning(årstal);
            produktionsomkostning = årsregnskabsColl.GetProduktionsomkostninger(årstal);
            bruttoresultat = årsregnskabsColl.GetBruttoresultat(årstal);
            distributionsomkostning = årsregnskabsColl.GetDistributionsomkostning(årstal);
            administrationsomkostning = årsregnskabsColl.GetAdministrationsomkostning(årstal);
            resultatPrimærDrift = årsregnskabsColl.GetResultatPrimærDrift(årstal);
            finansielOmkostningNetto = årsregnskabsColl.GetFinansielOmkostningNetto(årstal);
            åretsResultat = årsregnskabsColl.GetÅretsResultat(årstal);
        }

        // Metode til at udregne de resterende værdier i balancen
        public void UdregnBalancen(int årstal)
        {
            anlægsaktiver = årsregnskabsColl.GetAnlægsaktiver(årstal);
            omsætningsaktiver = årsregnskabsColl.GetOmsætningsaktiver(årstal);
            aktiverIAlt = årsregnskabsColl.GetAktiverIAlt(årstal);
            egenkapital = årsregnskabsColl.GetEgenkapital(årstal);
            gældsforpligtelser = årsregnskabsColl.GetGældsforpligtelser(årstal);
            passiverIAlt = årsregnskabsColl.GetPassiverIAlt(årstal);
        }

        #endregion

        #region Kald af metoder til at udregne og returnere nøgletallene til rentabilitetsanalysen

        // metode til at udregne nøgletallene til rentabilitetsanalysen
        public void UdregnRentabilitetsNøgletal(int årstal)
        {
            afkastningsgrad = årsregnskabsColl.GetAfkastningsgrad(årstal);
            overskudsgrad = årsregnskabsColl.GetOverskudsgrad(årstal);
            aktivernesOmsætningshastighed = årsregnskabsColl.GetAktivernesOmsætningshastighed(årstal);
            egenkapitalensForretning = årsregnskabsColl.GetEgenkapitalensForretning(årstal);
            fremmedkapitalensForretning = årsregnskabsColl.GetFremmedkapitalensForretning(årstal);
        }

        // kald af metode til at returnere afkastningsgraden
        public double GetAfkastningsgrad(int årstal)
        {
            return årsregnskabsColl.GetAfkastningsgrad(årstal);
        }

        // kald af metode til at returnere overskudsgraden
        public double GetOverskudsgrad(int årstal)
        {
            return årsregnskabsColl.GetOverskudsgrad(årstal);
        }

        // kald af metode til at returnere aktivernes omsætningshastighed
        public double GetAktivernesOmsætningshastighed(int årstal)
        {
            return årsregnskabsColl.GetAktivernesOmsætningshastighed(årstal);
        }

        // kald af metode til at returnere egenkapitalens forretning
        public double GetEgenkapitalensForretning(int årstal)
        {
            return årsregnskabsColl.GetEgenkapitalensForretning(årstal);
        }

        // kald af metode til at returnere fremmedkapitalens forretning
        public double GetFremmedkapitalensForretning(int årstal)
        {
            return årsregnskabsColl.GetFremmedkapitalensForretning(årstal);
        }

        #endregion

        #region Kald af metoder til at udregne og returnere nøgletallene til analysen af indtjeningsevnen

        // metode til at udregne nøgletallene til analysen af indtjeningsevnen
        public void UdregnIndtjeningsNøgletal(int årstal)
        {
            dækningsgrad = årsregnskabsColl.GetDækningsgrad(årstal);
            nulpunktsomsætning = årsregnskabsColl.GetNulpunktsomsætning(årstal);
            sikkerhedsMargin = årsregnskabsColl.GetSikkerhedsMargin(årstal);
            kapacitetsgrad = årsregnskabsColl.GetKapacitetsgrad(årstal);
        }

        // kald af metode til at returnere dækningsgraden
        public double GetDækningsgrad(int årstal)
        {
            return årsregnskabsColl.GetDækningsgrad(årstal);
        }

        // kald af metode til at returnere nulpunktsomsætningen
        public double GetNulpunktsomsætning(int årstal)
        {
            return årsregnskabsColl.GetNulpunktsomsætning(årstal);
        }

        // kald af metode til at returnere sikkerhedsmarginen
        public double GetSikkerhedsMargin(int årstal)
        {
            return årsregnskabsColl.GetSikkerhedsMargin(årstal);
        }

        // kald af metode til at returnere nulpunktsomsætningen
        public double GetKapacitetsgrad(int årstal)
        {
            return årsregnskabsColl.GetKapacitetsgrad(årstal);
        }

        #endregion

        #region Kald af metoder til at udregne og returnere nøgletallene til analysen af kapitaltilpasningen

        // metode til at udregne nøgletallene til analysen af kapitaltilpasningen
        public void UdregnKapitaltilpasningensNøgletal(int årstal)
        {
            anlægsaktivernesOmsætningshastighed = årsregnskabsColl.GetAnlægsaktivernesOmsætningshastighed(årstal);
            materielleOmsætningshastighed = årsregnskabsColl.GetMaterielleOmsætningshastighed(årstal);
            varelagrenesOmsætningshastighed = årsregnskabsColl.GetVarelagrenesOmsætningshastighed(årstal);
            lagerdage = årsregnskabsColl.GetLagerdage(årstal);
            varedebitorernesOmsætningshastighed = årsregnskabsColl.GetVaredebitorernesOmsætningshastighed(årstal);
            kreditdage = årsregnskabsColl.GetKreditdage(årstal);
        }

        // kald af metode til at returnere anlægsaktivernes omsætningshastighed
        public double GetAnlægsaktivernesOmsætningshastighed(int årstal)
        {
            return årsregnskabsColl.GetAnlægsaktivernesOmsætningshastighed(årstal);
        }

        // kald af metode til at returnere den materielle omsætningshastighed
        public double GetMaterielleOmsætningshastighed(int årstal)
        {
            return årsregnskabsColl.GetMaterielleOmsætningshastighed(årstal);
        }

        // kald af metode til at returnere varelagerets omsætningshastighed
        public double GetVarelagrenesOmsætningshastighed(int årstal)
        {
            return årsregnskabsColl.GetVarelagrenesOmsætningshastighed(årstal);
        }

        // kald af metode til at returnere lagerdage
        public double GetLagerdage(int årstal)
        {
            return årsregnskabsColl.GetLagerdage(årstal);
        }

        // kald af metode til at returnere varedebitorernes omsætningshastighed
        public double GetVaredebitorernesOmsætningshastighed(int årstal)
        {
            return årsregnskabsColl.GetVaredebitorernesOmsætningshastighed(årstal);
        }

        // kald af metode til at returnere kreditdage
        public double GetKreditdage(int årstal)
        {
            return årsregnskabsColl.GetKreditdage(årstal);
        }

        #endregion

        #region Kald af metoder til at udregne og returnere nøgletallene til analysen af soliditet og likviditet

        // metode til at udregne nøgletallene til analysen af soliditet og likviditet
        public void UdregnSoliditetOgLikviditetsNøgletal(int årstal)
        {
            soliditetsgrad = årsregnskabsColl.GetSoliditetsgrad(årstal);
            likviditetsgrad1 = årsregnskabsColl.GetLikviditetsgrad1(årstal);
            likviditetsgrad2 = årsregnskabsColl.GetLikviditetsgrad2(årstal);
        }

        // kald af metode til at returnere soliditetsgraden
        public double GetSoliditetsgrad(int årstal)
        {
            return årsregnskabsColl.GetSoliditetsgrad(årstal);
        }

        // kald af metode til at returnere likviditetsgrad 1
        public double GetLikviditetsgrad1(int årstal)
        {
            return årsregnskabsColl.GetLikviditetsgrad1(årstal);
        }

        // kald af metode til at returnere likviditetsgrad 2
        public double GetLikviditetsgrad2(int årstal)
        {
            return årsregnskabsColl.GetLikviditetsgrad2(årstal);
        }

        #endregion

        #endregion

        #region Operationer på medarbejder-objekter

        // Metode til at indlæse medarbejder-objekter i systemet
        public void IndlæsMedarbejdere(int medarbNr, string navn, string email, int tlfNr, string adresse, int postnr, string bynavn, bool aktiv)
        {
            medarbejderColl.OpretMedarbjeder(medarbNr, navn, email, tlfNr, adresse, postnr, bynavn, aktiv);
        }

        // metode til at oprette et medarbejder objekt
        public bool OpretMedarbejder(string navn, string email, int tlfNr, string adresse, int postnr, bool aktiv,
            out int medarbNr, out string bynavn)
        {
            if (dbFacade.OpretMedarbejder(navn, email, tlfNr, adresse, postnr, aktiv, out medarbNr))
            {
                if (dbFacade.GetBynavn(postnr, out bynavn))
                {
                    medarbejderColl.OpretMedarbjeder(medarbNr, navn, email, tlfNr, adresse, postnr, bynavn, aktiv);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                bynavn = "";
                return false;
            }
        }

        // metode til at redigere et medarbejder objekt.
        public bool RedigerMedarbejder(int medarbNr, string navn, string email, int tlfNr, string adresse,
            int postnr, bool aktiv, out string bynavn)
        {
            if (dbFacade.RedigerMedarbejder(medarbNr, navn, email, tlfNr, adresse, postnr, aktiv))
            {
                if (dbFacade.GetBynavn(postnr, out bynavn))
                {
                    medarbejderColl.RedigerMedarbejder(medarbNr, navn, email, tlfNr, adresse, postnr, bynavn, aktiv);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                bynavn = "";
                return false;
            }
        }

        // Kald af metode til at returnere medarbejder iterator
        public IEnumerator GetMedarbejdere()
        {
            return medarbejderColl.GetMedarbejdere();
        }

        // kald af metode til at finde et medarbejder-objekts nr udfra navnet
        public int GetMedarbNr(string navn)
        {
            return medarbejderColl.GetMedarbNr(navn);
        }

        #endregion

        #region Operationer på kunde-objekter

        // metode til at indlæse kunde-objekter i systemet
        public void IndlæsKunder(int kundeNr, int cvrNr, string firmanavn, string kontaktperson, string email, int tlfNr,
            string adresse, int postnr, string bynavn)
        {
            kundeColl.OpretKunde(kundeNr, cvrNr, firmanavn, kontaktperson, email, tlfNr, adresse, postnr, bynavn);
        }

        // metode til at oprette et kundeobjekt
        public bool OpretKunde(int cvrNr, string firmanavn, string kontaktperson, string email, int tlfNr, string adresse,
            int postnr, out int kundeNr, out string bynavn)
        {
            if (dbFacade.OpretKunde(cvrNr, firmanavn, kontaktperson, email, tlfNr, adresse, postnr, out kundeNr))
            {
                if (dbFacade.GetBynavn(postnr, out bynavn))
                {
                    kundeColl.OpretKunde(kundeNr, cvrNr, firmanavn, kontaktperson, email, tlfNr, adresse, postnr, bynavn);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                bynavn = "";
                return false;
            }
        }

        // metode til at redigere et kunde objekt
        public bool RedigerKunde(int kundeNr, int cvrNr, string firmanavn, string kontaktperson, string email, int tlfNr,
            string adresse, int postnr, out string bynavn)
        {
            if (dbFacade.RedigerKunde(kundeNr, cvrNr, firmanavn, kontaktperson, email, tlfNr, adresse, postnr))
            {
                if (dbFacade.GetBynavn(postnr, out bynavn))
                {
                    kundeColl.Redigerkunde(kundeNr, cvrNr, firmanavn, kontaktperson, email, tlfNr, adresse, postnr, bynavn);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                bynavn = "";
                return false;
            }
        }

        // kald af metode til at returnere kunde iterator
        public IEnumerator GetKunder()
        {
            return kundeColl.GetKunder();
        }

        #endregion

        #region Operationer på projekt-objekter

        #region Associeringsmetoder

        // metode til at associere et medarbejder-objekt til et projekt-objekt og omvendt
        public void AssocierProjektleder(int projektNr, int medarbNr)
        {
            Projekt projekt = projektColl.FindProjekt(projektNr);
            Medarbejder nyProjektleder = medarbejderColl.FindMedarbejder(medarbNr);

            Medarbejder tidligereProjektleder = projekt.GetMinProjektleder();
            if (tidligereProjektleder != null)
            {
                // fjener den gamle associering samt skaber en ny
                tidligereProjektleder.FjernProjekt(projekt);
                projekt.FjernProjektleder();
                projekt.TilknytProjektleder(nyProjektleder);
                nyProjektleder.TilknytProjekt(projekt);
            }
            else
            {
                projekt.TilknytProjektleder(nyProjektleder);
                nyProjektleder.TilknytProjekt(projekt);
            }
        }

        // metode til at associere et kunde-objekt til et projekt-objekt og omvendt
        public void AssocierKundeProjekt(int projektNr, int kundeNr)
        {
            Projekt projekt = projektColl.FindProjekt(projektNr);
            Kunde nyKunde = kundeColl.FindKunde(kundeNr);

            Kunde tidligereKunde = projekt.GetMinKunde();
            if (tidligereKunde != null)
            {
                // fjener den gamle associering samt skaber en ny
                tidligereKunde.FjernProjekt(projekt);
                projekt.FjernKunde();
                projekt.TilknytKunde(nyKunde);
                nyKunde.TilknytProjekt(projekt);
            }
            else
            {
                projekt.TilknytKunde(nyKunde);
                nyKunde.TilknytProjekt(projekt);
            }
        }

        // metode til at slette associeringen mellem et kunde-objekt og et projekt-objekt
        public void FjernAssocieringKundeProjekt(int projektNr, int kundeNr)
        {
            Projekt projekt = projektColl.FindProjekt(projektNr);
            kundeColl.FjernProjekt(kundeNr, projekt);
            projekt.FjernKunde();
        }

        // kald af metode til at hente et associeret kunde-objekt
        public IKundedata GetMinKunde(int projektNr)
        {
            return projektColl.GetMinKunde(projektNr);
        }

        // kald af metode til at hente et associeret medarbejder-objekt
        public IMedarbejderdata GetMinProjektleder(int projektNr)
        {
            return projektColl.GetMinProjektleder(projektNr);
        }

        #endregion

        // metode til at indlæse projekt-objekter i systemet
        public void IndlæsProjekter(int projektNr, string titel, DateTime starttidspunkt, string projektfase, string deadline, string tidsforbrug,
            DateTime sluttidspunkt, bool aktiv, int medarbNr)
        {
            projektColl.OpretProjekt(projektNr, titel, starttidspunkt, projektfase, deadline);
            projektColl.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv);
            AssocierProjektleder(projektNr, medarbNr);
        }

        // metode til at indlæse kundeprojekt-associeringer i systemet
        public void IndlæsKundeProjekter(int projektNr, int kundeNr)
        {
            AssocierKundeProjekt(projektNr, kundeNr);
        }

        // metode til at oprette et projekt-objekt
        public bool OpretProjekt(string titel, DateTime starttidspunkt, string projektfase, string deadline, int medarbNr,
            int kundeNr, out int projektNr)
        {
            if (dbFacade.OpretProjekt(titel, starttidspunkt, projektfase, deadline, medarbNr, out projektNr))
            {
                if (kundeNr > 0)
                {
                    if (dbFacade.OpretKundeProjekt(projektNr, kundeNr))
                    {
                        projektColl.OpretProjekt(projektNr, titel, starttidspunkt, projektfase, deadline);
                        AssocierKundeProjekt(projektNr, kundeNr);
                        AssocierProjektleder(projektNr, medarbNr);

                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    projektColl.OpretProjekt(projektNr, titel, starttidspunkt, projektfase, deadline);
                    AssocierKundeProjekt(projektNr, kundeNr);
                    AssocierProjektleder(projektNr, medarbNr);

                    return true;
                }
            }
            else
            {
                return false;
            }
        }

        // metode til at redigere et projekt-objekt
        public bool RedigerProjekt(int projektNr, string titel, DateTime starttidspunkt, string projektfase,
            string deadline, DateTime sluttidspunkt, bool aktiv, int kundeNr, int medarbNr)
        {
            string tidsforbrug;
            if (GetProjektetsTid(projektNr, out tidsforbrug))
            {
                if (dbFacade.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv, medarbNr))
                {
                    Kunde tidligereKunde = projektColl.GetMinKunde(projektNr);
                    if (kundeNr > 0 && tidligereKunde == null)
                    {
                        if (dbFacade.OpretKundeProjekt(projektNr, kundeNr))
                        {
                            projektColl.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv);
                            AssocierKundeProjekt(projektNr, kundeNr);
                            AssocierProjektleder(projektNr, medarbNr);

                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else if (kundeNr > 0 && tidligereKunde != null)
                    {
                        if (dbFacade.SletKundeProjekt(projektNr, tidligereKunde.KundeNr))
                        {
                            if (dbFacade.OpretKundeProjekt(projektNr, kundeNr))
                            {
                                projektColl.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv);
                                AssocierKundeProjekt(projektNr, kundeNr);
                                AssocierProjektleder(projektNr, medarbNr);

                                return true;
                            }
                            else
                            {
                                return false;
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else if (kundeNr == 0 && tidligereKunde != null)
                    {
                        if (dbFacade.SletKundeProjekt(projektNr, tidligereKunde.KundeNr))
                        {
                            projektColl.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv);
                            FjernAssocieringKundeProjekt(projektNr, tidligereKunde.KundeNr);
                            AssocierProjektleder(projektNr, medarbNr);

                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    }
                    else
                    {
                        projektColl.RedigerProjekt(projektNr, titel, starttidspunkt, projektfase, deadline, tidsforbrug, sluttidspunkt, aktiv);
                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        // metode til at opdatere et projekt-objekts tidsforbrug
        public bool OpdaterProjektsTidsforbrug(int projektNr)
        {
            string tidsforbrug;
            if (GetProjektetsTid(projektNr, out tidsforbrug))
            {
                if (dbFacade.OpdaterProjektsTidsforbrug(projektNr, tidsforbrug))
                {
                    projektColl.OpdaterProjektsTidsforbrug(projektNr, tidsforbrug);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }

        // metode at tilføje en tidsværdi til en liste af tider
        public void IndlæsTidArbejdsLog(int tid)
        {
            tidsListe.Add(tid);
        }

        // metode til at returnere et projekt-objekts samlede tidsværdi som minutter
        public bool GetProjektetsTid(int projektNr, out string tidsforbrug)
        {
            tidsListe.Clear();

            if (dbFacade.IndlæsTidArbejdsLog(projektNr))
            {
                int samletMin = 0;
                foreach (int tid in tidsListe)
                {
                    samletMin += tid;
                }

                int samletMinRest = samletMin % 60;
                int timer = (samletMin - samletMinRest) / 60;
                tidsforbrug = timer.ToString() + " t " + samletMinRest.ToString() + " min";

                return true;
            }
            else
            {
                tidsforbrug = "";
                return false;
            }
        }

        // metode til at returnere projekt iterator
        public IEnumerator GetProjekter()
        {
            return projektColl.GetProjekter();
        }

        #endregion

        #region Operationer på faktura- og vare-objekter

        // metode til at indlæse faktura-objekter fra databasen
        public void IndlæsFaktura(int fakturaNr, string valutaType, DateTime fakturadato, DateTime leveringsdato, DateTime betalingsdato,
            string betalingsmetode, string besked)
        {
            fakturaColl.OpretFaktura(fakturaNr, valutaType, fakturadato, leveringsdato, betalingsdato, betalingsmetode, besked);
        }

        // metode til at oprette et faktura-objekt i databasen og i systemet
        public bool OpretFaktura(string valutaType, DateTime fakturadato, DateTime leveringsdato, DateTime betalingsdato,
            string betalingsmetode, string besked, out int fakturaNr)
        {
            if (dbFacade.OpretFaktura(valutaType, fakturadato, leveringsdato, betalingsdato, betalingsmetode, besked, out fakturaNr))
            {
                fakturaColl.OpretFaktura(fakturaNr, valutaType, fakturadato, leveringsdato, betalingsdato, betalingsmetode, besked);
                return true;
            }
            else
            {
                return false;
            }
        }

        // metode til at udregne subtotalEkskl, momsBeløb og total
        public void UdregnTalTilFaktura(int fakturaNr)
        {
            fakturaColl.UdregnSubtotalEkskl(fakturaNr);
            fakturaColl.UdregnMomsBeløb(fakturaNr);
            fakturaColl.UdregnTotal(fakturaNr);
        }

        // kald af metode til at hente faktura iterator
        public IEnumerator GetFakturaer()
        {
            return fakturaColl.GetFakturaer();
        }

        // metode til at give objektet/attributten iFaktura sit indhold
        public void UdfyldIFaktura(int fakturaNr)
        {
            iFaktura.Clear();
            IFakturadata iFakturaData;
            IEnumerator iFakturaIterator = GetFakturaer();
            iFakturaIterator.Reset();

            while (iFakturaIterator.MoveNext())
            {
                iFakturaData = (IFakturadata)iFakturaIterator.Current;

                if (iFakturaData.FakturaNr == fakturaNr)
                {
                    iFaktura.Add(iFakturaData);
                }
            }
        }

        // metode til at indlæse vare-objekter fra databasen
        public void IndlæsVare(int fakturaNr, int vareID, string varebeskrivelse, int antal, string enhed, double prisPrEnhedEkskl, 
            double moms, double varetotalEkskl)
        {
            fakturaColl.OpretVare(fakturaNr, vareID, varebeskrivelse, antal, enhed, prisPrEnhedEkskl, moms, varetotalEkskl);
        }

        // metode til at oprette et vare-objekt i databasen og i systemet
        public bool OpretVare(int fakturaNr, string varebeskrivelse, int antal, string enhed, double prisPrEnhedEkskl, double moms, 
            double varetotalEkskl, out int vareID)
        {
            if (dbFacade.OpretVare(fakturaNr, varebeskrivelse, antal, enhed, prisPrEnhedEkskl, moms, varetotalEkskl, out vareID))
            {
                fakturaColl.OpretVare(fakturaNr, vareID, varebeskrivelse, antal, enhed, prisPrEnhedEkskl, moms, varetotalEkskl);
                return true;
            }
            else
            {
                return false;
            }
        }

        // kald af metode til at udregne varetotalEkskl
        public void UdregnTalTilFaktura(int fakturaNr, int vareID)
        {
            fakturaColl.UdregnVaretotalEkskl(fakturaNr, vareID);
        }

        // kald af metode til at hente vare iterator
        public IEnumerator GetVarer(int fakturaNr)
        {
            return fakturaColl.GetVarer(fakturaNr);
        }

        // kald af metode til at finde et faktura-objekts antal af vare-objekter
        public int GetAntalVarer(int fakturaNr)
        {
            return fakturaColl.GetAntalVarer(fakturaNr);
        }

        // metode til at give objektet/attributten iFaktura sit indhold
        public void UdfyldIVarer(int fakturaNr)
        {
            iVarer.Clear();
            IVaredata iVare;
            IEnumerator iVareIterator = GetVarer(fakturaNr);
            iVareIterator.Reset();

            while (iVareIterator.MoveNext())
            {
                iVare = (IVaredata)iVareIterator.Current;

                iVarer.Add(iVare);
            }
        }

        #endregion

        // kald af metode til at sende en mail
        public void SendMail(string modtager, string emne, string besked, string filPlacering)
        {
            mailAccount.SendMessage(modtager, emne, besked, filPlacering);
        }

        #region Properties

        // get properties af hensyn til rapportgenereringen
        public IÅrsregnskabsdata IÅrsregnskab
        {
            get { return iÅrsregnskab; }
        }

        public List<IFakturadata> IFaktura
        {
            get { return iFaktura; }
        }

        public List<IVaredata> IVarer
        {
            get { return iVarer; }
        }

        public double NettoOmsætning
        {
            get { return nettoOmsætning; }
        }

        public double Produktionsomkostninger
        {
            get { return produktionsomkostning; }
        }

        public double Bruttoresultat
        {
            get { return bruttoresultat; }
        }

        public double Distributionsomkostning
        {
            get { return distributionsomkostning; }
        }

        public double Administrationsomkostning
        {
            get { return administrationsomkostning; }
        }

        public double ResultatPrimærDrift
        {
            get { return resultatPrimærDrift; }
        }

        public double FinansielOmkostningNetto
        {
            get { return finansielOmkostningNetto; }
        }

        public double ÅretsResultat
        {
            get { return åretsResultat; }
        }

        public double Anlægsaktiver
        {
            get { return anlægsaktiver; }
        }

        public double Omsætningsaktiver
        {
            get { return omsætningsaktiver; }
        }

        public double AktiverIAlt
        {
            get { return aktiverIAlt; }
        }

        public double Egenkapital
        {
            get { return egenkapital; }
        }

        public double Gældsforpligtelser
        {
            get { return gældsforpligtelser; }
        }

        public double PassiverIAlt
        {
            get { return passiverIAlt; }
        }

        public double Afkastningsgrad
        {
            get { return afkastningsgrad; }
        }
        public double Overskudsgrad
        {
            get { return overskudsgrad; }
        }

        public double AktivernesOmsætningshastighed
        {
            get { return aktivernesOmsætningshastighed; }
        }

        public double EgenkapitalensForretning
        {
            get { return egenkapitalensForretning; }
        }

        public double FremmedkapitalensForretning
        {
            get { return fremmedkapitalensForretning; }
        }

        public double Dækningsgrad
        {
            get { return dækningsgrad; }
        }

        public double Nulpunktsomsætning
        {
            get { return nulpunktsomsætning; }
        }

        public double SikkerhedsMargin
        {
            get { return sikkerhedsMargin; }
        }

        public double Kapacitetsgrad
        {
            get { return kapacitetsgrad; }
        }

        public double AnlægsaktivernesOmsætningshastighed
        {
            get { return anlægsaktivernesOmsætningshastighed; }
        }

        public double MaterielleOmsætningshastighed
        {
            get { return materielleOmsætningshastighed; }
        }

        public double VarelagrenesOmsætningshastighed
        {
            get { return varelagrenesOmsætningshastighed; }
        }

        public double Lagerdage
        {
            get { return lagerdage; }
        }

        public double VaredebitorernesOmsætningshastighed
        {
            get { return varedebitorernesOmsætningshastighed; }
        }

        public double Kreditdage
        {
            get { return kreditdage; }
        }

        public double Soliditetsgrad
        {
            get { return soliditetsgrad; }
        }

        public double Likviditetsgrad1
        {
            get { return likviditetsgrad1; }
        }

        public double Likviditetsgrad2
        {
            get { return likviditetsgrad2; }
        }

        #endregion
    }
}
